home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / The World of Computer Software.iso / proxy11.zip / PROXY.DOC < prev    next >
Text File  |  1992-12-29  |  59KB  |  1,921 lines

  1.  
  2.  
  3.  
  4.  
  5.  
  6.  
  7.                        PROXY USERS GUIDE
  8.  
  9.                          Version 1.1
  10.  
  11.                        EDL Software Design
  12.                        23419 S. Mirabella Circle
  13.                        Boca Raton, FL 33433
  14.  
  15.             Copyright (c) 1991, 1992, 1993 by Burt Leavenworth
  16.                        All Rights Reserved
  17.  
  18.  
  19. COPYRIGHT NOTICE
  20.  
  21. Proxy is not a public domain program. It is Copyright (C) 1991, 1992,
  22. 1993 by Burt Leavenworth.
  23.  
  24. LICENSE
  25.  
  26. Non-registered users are granted a limited license to use Proxy
  27. on a trial basis for the purpose of determining whether Proxy is
  28. suitable for their needs. Use of Proxy, except for this limited
  29. purpose, requires registration (see the file PROXY.REG). Any
  30. non-registered use, other than the above, is strictly prohibited.
  31.  
  32. No user may modify Proxy in any way, including but not limited to
  33. decompiling, disassembling or otherwise reverse engineering the
  34. program. All users are granted a limited license to copy Proxy
  35. only for the trial use of others subject to the above limitations
  36. provided that the full Proxy documentation, including license,
  37. warranty and registration information, must be copied. No fee,
  38. charge or other compensation may be accepted or requested by
  39. any licensee.
  40.  
  41. Operators of electronic bulletin board systems (BBSs) may post
  42. Proxy for downloading by their users only as long as the above
  43. conditions are met. Distributors of user supported software
  44. (disk vendors) may also distribute copies of Proxy subject to
  45. the above conditions.
  46.  
  47. WARRANTY INFORMATION
  48.  
  49. The author hereby disclaims all warranties relating to this
  50. software, whether express or implied, including without
  51. limitation any implied warranties of merchantability or fitness
  52. for a particular purpose. The author will not be liable for any
  53. special, incidental, consequential, indirect or similar damages
  54. including any lost profits or lost savings, arising from the use
  55. of, or inability to use, this software, even if the author has
  56. been advised of the possibility of such damages.
  57.  
  58. TABLE OF CONTENTS
  59.  
  60. Introduction ............................................  2
  61.  
  62.  
  63.  
  64.  
  65.  
  66.  
  67.  
  68.  
  69.  
  70.                                      Page 2
  71.  
  72.  
  73. Getting Started .........................................  2
  74. Using Commands ..........................................  3
  75.   Primitive Types .......................................  4
  76.   Identifiers ...........................................  4
  77.   Operators .............................................  4
  78.   Sets ..................................................  4
  79.   Maps ..................................................  6
  80.   Sequences .............................................  8
  81.   Strings ............................................... 10
  82.   Structs ............................................... 10
  83.   Operator Precedence ................................... 11
  84.   Function Definition ................................... 11
  85.   Class Definition ...................................... 12
  86.   System Commands ....................................... 14
  87. Using Statements ........................................ 18
  88.   Assignment Statement .................................. 18
  89.   Conditional Statement ................................. 18
  90.   While Statement ....................................... 18
  91.   For Statement ......................................... 18
  92.   Return Statements ..................................... 19
  93.   I/O Statements ........................................ 19
  94.   Function Call ......................................... 20
  95.   Block ................................................. 20
  96.   Comments .............................................. 20
  97. Type Predicates ......................................... 20
  98. Class Constructors ...................................... 21
  99. Scheme Interface ........................................ 21
  100. An Example .............................................. 22
  101. Another Example ......................................... 23
  102. Proxy Keywords .......................................... 26
  103. References .............................................. 27
  104. Index ................................................... 27
  105.  
  106. INTRODUCTION
  107.  
  108. Proxy is an interpreter for a rapid prototyping language with C
  109. and C++ like syntax based on modelling software using data
  110. structures such as sets, maps, sequences, and objects. There are
  111. no pointers or arrays in Proxy (although maps can be thought of
  112. as a high level generalized array), which avoids the temptation
  113. to use these rather low level types. Proxy has been influenced
  114. to a great extent by the "me too"[1], VDM [3], EPROL [4], and
  115. SETL [5] languages. Proxy allows the developer to make incremental
  116. changes to a design, and test them immediately. It therefore
  117. follows Fred Brooks' injunction: "Plan to throw one away: you
  118. will, anyhow" [2].
  119.  
  120. A software system can be represented as a "state" and a collection of
  121. functions which operate on components of the state. The user may
  122. develop these operations incrementally or define them in files which
  123. are loaded prior to execution. It is also possible to manipulate
  124. objects (defined by classes) which encapsulate local states; this
  125. allows the user to define a software model as a hierarchy of submodels.
  126.  
  127.  
  128.  
  129.  
  130.  
  131.  
  132.  
  133.  
  134.  
  135.  
  136.                                      Page 3
  137.  
  138.  
  139. GETTING STARTED
  140.  
  141. The following files are provided with the Proxy system:
  142.  
  143.      PROXY.EXE                   QUICKSRT.PRX
  144.      PROXY.DAT                   BINTREE.PRX
  145.      PROXY.INI                   TOPSORT.PRX
  146.      PROXY.DOC                   PRIMES.PRX
  147.      PROXY.REG                   CROSS.PRX
  148.      PRNTDOC.EXE                 EMAIL.PRX
  149.      PRINTDOC.BAT                DATAFLOW.TXT
  150.      FINANCE.PRX                 READ.ME
  151.  
  152. Copy the files into a subdirectory of your choice. To install Proxy,
  153. move to that subdirectory, type
  154.  
  155.      proxy install
  156.  
  157. and press <enter>.
  158.  
  159. The install process will end with the message:
  160.  
  161. loading-ended
  162.  
  163. To run Proxy, type
  164.  
  165.      proxy
  166.  
  167. After the copyright notice, the following will be displayed
  168. on your screen:
  169.  
  170.  Continue? : (run) / (exit)
  171.  
  172.  >
  173.  
  174. Type (run) and press <enter>. Make sure that run is enclosed by
  175. parentheses. A prompt ? will be displayed. You may now type
  176. expressions and function definitions. To print out the
  177. documentation, type printdoc and press <enter>. To get help
  178. at any prompt, type: help; and press <enter>. To exit the
  179. interpreter from any prompt, type exit; and press <enter>. Whenever
  180. the Continue? : (run) / (exit) prompt appears, you may exit the
  181. interpreter by typing (exit) and pressing <enter>.
  182.  
  183. Note - If you change to a new memory mapping scheme, for example,
  184. upgrading to DOS 5.0, it will be necessary to re-install Proxy.
  185.  
  186. USING COMMANDS
  187.  
  188. There are two types of commands: "desk calculator" type commands,
  189. and system commands. There are four system commands: load (to load
  190. a Proxy file), transcript (to store in a file a transcript of all
  191. subsequent keystrokes), help (to obtain the syntax of different
  192. commands, statements, and composite data structures), and exit (to
  193.  
  194.  
  195.  
  196.  
  197.  
  198.  
  199.  
  200.  
  201.  
  202.                                      Page 4
  203.  
  204.  
  205. return to the DOS prompt). "Desk calculator" commands are the expressions,
  206. assignments, and definitions that can be typed at the Proxy prompt for
  207. immediate evaluation and execution.
  208.  
  209. Commands are typed at the Proxy prompt. The simplest command is an
  210. expression to be evaluated, i.e. 2+2;. Note that every command
  211. must be terminated with a semi-colon. There are four (primitive)
  212. types of expressions.
  213.  
  214. Primitive types
  215.  
  216. The primitive data types are integer, real, boolean, and string.
  217. Real literals are written in decimal form, i.e. 3.14159; there
  218. must be at least one digit before the decimal point. Boolean
  219. literals are written true, false, and strings are written with
  220. double quotes, i.e. "This is a string".
  221.  
  222. Slightly more complicated expressions involve identifiers (variables):
  223.  
  224. Identifiers
  225.  
  226. All identifiers must start with a letter. The rest of the identifier
  227. can consist of letters, underscores or digits. Identifiers are not
  228. case sensitive, i.e. aBcD is considered to be the same identifier as
  229. abcd.
  230.  
  231. Operators
  232.  
  233. The standard arithmetic, relational and Boolean operators are supported
  234. wuth their relative precedence given by the following table:
  235.  
  236.      !   unary -                          highest
  237.      * / %  &&                              |
  238.      + - ||                                 v
  239.      == != < > <= >=                      lowest
  240.  
  241. where ! represents logical negation, % is the modulo operator, && is
  242. logical conjunction, || is logical disjunction, == represents equal
  243. and != represents not equal.
  244.  
  245. Another command is assigning a value to an identifier. For example,
  246.  
  247. x=2;
  248.  
  249. We can then invoke the expression x+3;
  250.  
  251. More complicated expressions can be formed using the composite data
  252. types provided by Proxy: sets, maps, sequences and structs.
  253.  
  254. Sets
  255.  
  256. A mathematical set is, of course, an unordered collection of elements.
  257. From a formal point of view, each element should have the same type.
  258. However, since Proxy has latent types, i.e. types are not declared by
  259.  
  260.  
  261.  
  262.  
  263.  
  264.  
  265.  
  266.  
  267.  
  268.                                      Page 5
  269.  
  270.  
  271. the programmer, set elements are not restricted to have the same type.
  272.  
  273. The simplest operation is to enumerate a set by delimiting its elements
  274. by curly brackets:
  275.  
  276. {1,2,3,4,5}
  277.  
  278. This same set can be constructed by using the range notation
  279. (not to be confused with the range of a map to be defined later)
  280.  
  281. {1..5}
  282.  
  283. Ranges can only be used when the elements are consecutive. Another
  284. example of enumeration would be
  285.  
  286. smallprimes = {2,3,5,7};
  287.  
  288. To find the number of elements in the set smallprimes, we use the
  289. cardinality operator card:
  290.  
  291. card smallprimes;      returns 4
  292.  
  293. Two sets can be tested for equality using the equality operator ==.
  294.  
  295. Another simple operation is membership:
  296.  
  297. 3 in smallprimes;      returns true
  298.  
  299. 3 notin smallprimes:   returns false
  300.  
  301. To illustrate the standard operations of union, intersection, difference
  302. subset and equality, we assume two sets s1 and s2 to have the values
  303.  
  304. s1={1,2,4,6};
  305.  
  306. s2={1,2,3,4,5};
  307.  
  308. s1 U s2;               returns {1,2,3,4,5,6}
  309. s1 inter s2;           returns {1,2,4}
  310. s1 diff s2;            returns {6}
  311. s1 subset s2;          returns false
  312. s1 == s2;              returns false
  313.  
  314. The distributed union is the union of a set of sets. For example,
  315.  
  316. union {s1,s2,{6,7,8}};       returns {1,2,3,4,5,6,7,8}
  317.  
  318. The 'the' operator returns the only element of a singleton set. If
  319. the argument is not a singleton set, an error message is returned.
  320.  
  321. the {13};              returns 13
  322.  
  323. The oneof operator applied to a set returns an 'arbitrary' element
  324. of the set. However, Proxy always returns the 'first' element.
  325.  
  326.  
  327.  
  328.  
  329.  
  330.  
  331.  
  332.  
  333.  
  334.                                      Page 6
  335.  
  336.  
  337.  
  338. oneof smallprimes;     returns 2
  339.  
  340. The existential quantifier applied to a set and a predicate returns
  341. true if there is at least one element of the set that satisfies the
  342. predicate, and false otherwise. The universal quantitifer applied
  343. to a set and a predicate returns true only if all elements of the set
  344. satify the predicate.
  345.  
  346. (exists x in {2,3,5,7};even(x));  returns true
  347.  
  348. (all x in {2,3,5,7};even(x));     returns false
  349.  
  350. where the function even(x) returns true if x is even. The existential
  351. quantifier above returns true because 2 satisfies even(2) and the
  352. universal quantifier returns false because only even(2) is satisfied.
  353.  
  354. A more general way of constructing sets is given by the form:
  355.  
  356. { f(x): x<- expr ; pred(x) }
  357.  
  358. where the syntax x<- expr is called a generator, and the syntax
  359. ; pred(x) is optional. The expression expr is evaluated to
  360. yield a set. The values of the set are successively assigned to x
  361. and a new set is formed from elements obtained by applying the function
  362. f to the successive values of x which satisfy pred(x) (if pred(x) occurs).
  363. Several examples will make this clearer.
  364.  
  365. { x: x<- {1,2,3,4,5}};           returns {1,2,3,4,5}
  366.  
  367. This is the simplest case where f(x) is just x and a predicate does
  368. not appear.
  369.  
  370. { x: x <- {1,2,3,4,5};x>2};      returns {3,4,5}
  371.  
  372. { x*x: x <- {1,2,3,4,5}};        returns {1,4,9,16,25}
  373.  
  374. It is possible to have two generators in which case an example is:
  375.  
  376. { x+y: x <- {1,2}, y <- {3,4}}   returns  {4,5,6}
  377.  
  378. Only three elements are returned because two additions (1+4) and (2+3)
  379. yield duplicate values.
  380.  
  381.  
  382. Maps
  383.  
  384. Maps are also enumerated by delimiting their elements with curly
  385. brackets (because formally maps are sets of ordered pairs). The
  386. syntax is given by the following example.
  387.  
  388. m = {1->2,3->4,5->6};
  389.  
  390. where the first and second elements of each ordered pair is separated
  391.  
  392.  
  393.  
  394.  
  395.  
  396.  
  397.  
  398.  
  399.  
  400.                                      Page 7
  401.  
  402.  
  403. by the mapping symbol ->.
  404.  
  405. Maps can be constructed using map construction. In the following
  406. example, len returns the length of a string.
  407.  
  408. {x->len x:x <- {"abc","defg","hijkl"}};
  409.  
  410.          returns {"abc"->3,"defg"->4,"hijkl"->5}
  411.  
  412. The domain (range) of a map is obtained by forming a set composed
  413. of all the first (second) elements of the ordered pairs
  414.  
  415. dom m;               returns {1,3,5}
  416. rng m;               returns {2,4,6}
  417.  
  418. A single-valued map must have all its first elements unique. Notice
  419. that, in general, card (rng m) <= card (dom m). The cardinality of
  420. the range would be less, for example if
  421.  
  422. m = {1->2,3->2,5->6};
  423.  
  424. In this case, card(dom m) = 3, and card(rng m) = 2 (because of the
  425. duplicate elements in the range).
  426.  
  427. Given a domain element, we can obtain the corresponding range element
  428. using application (this is like a table lookup).
  429.  
  430. m[1];                returns 2
  431. m[5];                returns 6
  432.  
  433. If a domain element is given which does not exist in the map, a false
  434. value will be returned. However, it is possible to supply your own
  435. value to be returned in this situation. This is done by supplying an
  436. additional argument (called the default error return). For example,
  437.  
  438. m[7];                returns false
  439. m[7,"not found"];    returns "not found"
  440.  
  441. Given a set of domain elements as a second argument, the image operation
  442. (im) produces a set of the corresponding range elements (again assuming
  443. m={1->2,3->4,5->6})
  444.  
  445. m im {3,5};        returns {4,6}
  446.  
  447. Domain restriction (dr) and domain subtraction (ds) produce new maps
  448. from a given map by either allowing only certain domain elements in
  449. the given map to appear in the result map, or taking away certain
  450. domain elements from the given map. The domain elements are given
  451. in a set which is the second argument of these operations.
  452.  
  453. {1->2,3->2,5->6} dr {3,5};     returns  {3->2,5->6}
  454. {1->2,3->2,5->6} ds {3,5};     returns {1->2}
  455.  
  456. The inverse operation just interchanges the domain and range elements
  457.  
  458.  
  459.  
  460.  
  461.  
  462.  
  463.  
  464.  
  465.  
  466.                                      Page 8
  467.  
  468.  
  469. of a map.
  470.  
  471. inverse {1->2,3->2,5->6};      returns {2->1,2->3,6->5}
  472.  
  473. Note that the result of the above operation is a multi-valued map.
  474.  
  475. The overwrite operation m1 overwr m2 is defined as follows: Each
  476. mapping in m1 is included in the result, unless its domain element
  477. occurs in the domain of m2. In that case, it is replaced by the
  478. mapping from m2. Every mapping in m2 whose domain element does not
  479. occur in the domain of m1 is included in the result. Example:
  480.  
  481. {1->2,3->4} overwr {3->5,4->6};    returns {1->2,3->5,4->6}
  482.  
  483. The map update m[d]=r is an assignment and a special case of
  484. overwrite where the second operand (of overwrite) contains a
  485. single ordered pair. Assuming that m is equal to {1->2,3->4},
  486. m[3]=5; is equivalent to m overwr {3->5} and assigns to m the map
  487. {1->2,3->5}.
  488.  
  489. Sequences
  490.  
  491. A sequence is a collection of ordered elements which may be
  492. selected by their ordinal position (index) in the sequence. The
  493. types of the elements are not necessarily the same.
  494.  
  495. A sequence can be enumerated by delimiting its elements by square
  496. brackets:
  497.  
  498. [1,2,3,4,5]
  499.  
  500. This same sequence can be constructed by using the range (not to be
  501. confused with the range of a map) notation:
  502.  
  503. [1..5]
  504.  
  505. Ranges can only be used when the elements are consecutive. Another
  506. example of enumeration would be
  507.  
  508. s1 = [1,2,2,3,4];
  509.  
  510. Note the duplicate elements. To find the number of elements in the
  511. sequence s1, we use the length operator len:
  512.  
  513. len s1;                   returns 5
  514.  
  515. Two sequences can be tested for equality using the equality operator
  516. ==. Concatenation of two sequences is performed used the concatenation
  517. operator conc.
  518.  
  519. [1,2,3,4] conc [3,4,5];   returns [1,2,3,4,3,4,5]
  520.  
  521. If s=[3,4,5], then an element of the sequence can be selected using
  522. its index in the sequence. For example,
  523.  
  524.  
  525.  
  526.  
  527.  
  528.  
  529.  
  530.  
  531.  
  532.                                      Page 9
  533.  
  534.  
  535.  
  536. s[1];                     returns 3
  537. s[3];                     returns 5
  538. s[4];                     returns false
  539. s[4,0];                   returns 0
  540.  
  541. The last example uses the default error return.
  542.  
  543. Other selection operators on sequences are hd, tl, last and butlast.
  544. Hd returns the first element of the sequence. Tl returns a sequence
  545. consisting of every element but the first. Last returns a sequence
  546. consisiting of only the last element. Butlast returns a sequence
  547. consisting of every element but the last.
  548.  
  549. hd s;                     returns 3
  550. tl s;                     returns [4,5]
  551. last s;                   returns [5]
  552. butlast s;                returns [3,4]
  553.  
  554. A sequence of length n can be represented by a map whose range elements
  555. are the elements of the sequence, and whose domain elements are the
  556. integers from 1 to n. Consequently, the domain operator applied to a
  557. sequence will return the index elements {1..n}, and the range operator
  558. will return the elements of the sequence contained in a set.
  559.  
  560. dom s;                    returns {1,2,3}
  561. rng s;                    returns {3,4,5}
  562.  
  563. A sequence can be converted explicitly to its corresponding map and
  564. conversely. Thus
  565.  
  566. m=seq2map s;              assigns to m the map {1->3,2->4,3->5}
  567. map2seq m;                returns [3,4,5]
  568.  
  569. A more general way of constructing sequences, analogous to set
  570. construction is given by the following form
  571.  
  572. [ f(x): x<- expr ; pred(x) ]
  573.  
  574. where the syntax x<- expr is called a generator, and the syntax
  575. ; pred(x) is optional. The expression expr is evaluated to
  576. yield a sequence. The values of the sequence are successively assigned
  577. to x and a new sequence is formed from elements obtained by applying the
  578. function f to the successive values of x which satisfy pred(x) (if pred(x)
  579. occurs). An example:
  580.  
  581. [len x: x<-["abc","defg","hijkl"];len x > 3];  returns [4,5]
  582.  
  583. Before concluding a discussion of sequences, it is important to point
  584. out a distinction between a sequence of length two and an orderd pair.
  585. Remember that a map may be considered to be a set of ordered pairs.
  586. There are cases when one needs to access the components of an ordered
  587. pair. Proxy provides two operators for this purpose, first and second.
  588.  
  589.  
  590.  
  591.  
  592.  
  593.  
  594.  
  595.  
  596.  
  597.  
  598.                                      Page 10
  599.  
  600.  
  601. {first x:x<-{1->2,3->4,5->6}};     returns {1,3,5}
  602.  
  603. Suppose now that we have a set of sequences, say y={[1,2],[3,4]}
  604. and we wish to obtain a set of the first elements of the sequences.
  605. It would be wrong to write {first x:x<-y}. The correct solution is to
  606. write {x[1]:x<-y}.
  607.  
  608. Strings
  609.  
  610. Strings can be considered to be sequences of characters, although
  611. a character is not a primitive type in Proxy. Since the string
  612. operators are similar to the sequence operators already discussed,
  613. their use will be shown below in examples.
  614.  
  615. len "abcd";                      returns 4
  616. "abc" == "abc";                  returns true
  617. "abc" == "aBc";                  returns false
  618. "abc" < "abcd";                  returns true
  619. "abc" conc "defg";               returns "abcdefg"
  620. s="abc";
  621. s[2];                            returns "b"
  622. s[4];                            returns false
  623. s[4,0];                          returns 0
  624. hd "abc";                        "a"
  625. tl "abc";                        "bc"
  626. last "abc";                      "c"
  627. butlast "abc";                   "ab"
  628.  
  629. Structs
  630.  
  631. Structs are data structures whose components may be selected by name.
  632. The typical operations are declaration, instantiation, selection and
  633. update.
  634.  
  635. A struct declaration is essentially a class declaration which defines
  636. the names of the components of the struct. The syntax of the declaration
  637. is best shown by an example.
  638.  
  639. struct item {partno, code, quantity;};
  640.  
  641. The above declaration defines item to be a struct with the (field)
  642. names partno, code and quantity. Various items can be instantiated
  643. (created) by providing the struct name and values for the fields.
  644. (but a struct component may not be a function).
  645.  
  646. i1=new item(124,"receipt",15);
  647. i2=new item(126,"issue",7);
  648.  
  649. Components of structs may be selected using a dot notation similar
  650. to records in Pascal and structures in C.
  651.  
  652. i1.code;                   returns "receipt"
  653. i2.quantity;               returns 7
  654.  
  655.  
  656.  
  657.  
  658.  
  659.  
  660.  
  661.  
  662.  
  663.  
  664.                                      Page 11
  665.  
  666.  
  667. Component values may be updated using assignment and dot notation.
  668.  
  669. i1.quantity=22;            assigns 22 as the new value of the quantity
  670.                            field.
  671.  
  672. Operator Precedence
  673.  
  674. The precedence of Proxy operators from highest to lowest are
  675. shown below.
  676.  
  677.      unary operators                                   HIGHEST
  678.      * / % && inter conc dr ds im                         |
  679.      + - || U overwr                                      v
  680.      == != < > <= >= in notin subset equiv implies      LOWEST
  681.  
  682. where the unary operators are:
  683.  
  684.      - + ! hd tl last butlast card len first dom rng
  685.      union the oneof map2seq seq2map new inverse
  686.  
  687. Function Definition
  688.  
  689. The syntax of function definition in Proxy is the same as that in C
  690. with minor differences: (1) the declaration of local variables is different
  691. mainly due to the fact that the types of variables are not declared in
  692. Proxy and (2) each function declaration in Proxy is terminated with a
  693. semi-colon, (3) it is not necessary to name the top level function 'main',
  694. (4) procedures do not require the prefix 'void'; in what follows we will
  695. use the generic term function to apply as well to procedures. The syntax
  696. is now shown:
  697.  
  698. identifier ( op-param-list op-decl) block ;
  699.  
  700. The definition consists of the function name (identifier) followed by
  701. an optional parameter-list and an optional list of local variables
  702. delimited by parentheses. The parameter-list consists of identifiers
  703. separated by commas. The list of local variables consists of a semi-
  704. colon followed by identifiers separated by commas. The block consists
  705. of a statement-list (see the section on statements) delimited by
  706. curly brackets. Finally, the definition must be terminated with a
  707. semi-colon. Examples follow (the return statement is described in the
  708. section on statements).
  709.  
  710. even(n) {return n%2==0;};
  711. odd(n) {return !even(n);};
  712.  
  713. Given a subset of the integers, say digits={0..9};, we can define
  714. a function to obtain the odd integers from this set.
  715.  
  716. odddigits() {return {n:n<-digits;odd(n)};};
  717.  
  718. The following example illustrates a simple recursive function to
  719. add up the elements in an integer sequence.
  720.  
  721.  
  722.  
  723.  
  724.  
  725.  
  726.  
  727.  
  728.  
  729.  
  730.                                      Page 12
  731.  
  732.  
  733. reduce(s) { if(s==[]) return 0; else return hd s + reduce(tl s);};
  734.  
  735. The next example illustrates the definition of a doubly recursive
  736. function, and the declaration of a local variable x.
  737.  
  738. quicksort(s;x) { if(len s<2) return s;
  739.               x=s[1];
  740.               return quicksort([y:y<-s;y<x]) conc [x]
  741.                 conc quicksort([y:y<-tl s;y>=x]);};
  742.  
  743. An example showing the use of the existential quantifier:
  744.  
  745. primes(max) {return [n:n<-[2..max];
  746.              !(exists m in {2..n-1};(n % m)==0)];};
  747.  
  748.  
  749. An example of a procedure (a function which does not contain a return
  750. statement) which has no parameters.
  751.  
  752. init() {x["a"]="b";};
  753.  
  754. This procedure initializes the variable x to the map {"a"->"b"}. The
  755. same effect could have been achieved at the command level by the
  756. assignment x["a"]="b";.
  757.  
  758. Class Definition and Instantiation
  759.  
  760. A class is defined by giving the class name, followed by an
  761. enumeration of instance variables in the form of a
  762. parameter list, followed by a collection of function definitions
  763. (also called methods). Classes, contrary to C++, may only contain
  764. functions.
  765.  
  766. In order to motivate the definition and usage of a class, let us first
  767. define a simple queue. It does not matter what type of item the queue
  768. contains; we will assume a queue of integers. In the specification
  769. below, the state component q (a global variable) represents the queue
  770. as a sequence, which is initialized as the empty sequence.
  771.  
  772. q=[];
  773. enqueue(x) {q=q conc [x];};
  774. dequeue(;x) {x=hd q;q=tl q;return x;};
  775. empty() {return q==[];};
  776. length() {return len q;};
  777.  
  778. A typical sequence of operations is:
  779.  
  780. ? enqueue(3);
  781.  
  782. ? enqueue(5);
  783.  
  784. ? length();
  785.  2
  786.  
  787.  
  788.  
  789.  
  790.  
  791.  
  792.  
  793.  
  794.  
  795.  
  796.                                      Page 13
  797.  
  798.  
  799. ? dequeue();
  800.  3
  801.  
  802. ? empty();
  803.  false
  804.  
  805. ? dequeue();
  806.  5
  807.  
  808. ? empty();
  809.  true
  810.  
  811. There are drawbacks to this approach. Only one queue is available, and
  812. its representation is completely exposed. The problem can be solved by
  813. defining a queue class.
  814.  
  815. class queue(rep) {
  816.  
  817. enqueue(x) {rep=rep conc [x];}
  818. dequeue(;y) {y=hd rep;rep=tl rep; return y;}
  819. empty() {return rep==[];}
  820. length() {return len rep;}};
  821.  
  822. The coding is very similar except now the state component (rep) is local
  823. and is hidden inside the class definition. The representation is
  824. initialized from the outside and may only be changed indirectly by
  825. invoking either the enqueue or dequeue operation. The analogous sequence
  826. of operations is:
  827.  
  828. ? q=new queue([]);
  829.  
  830. ? q.enqueue(3);
  831.  
  832. ? q.enqueue(5);
  833.  
  834. ? q.length;                    or q.length();
  835.  2
  836.  
  837. ? q.dequeue;                   or q.dequeue();
  838.  3
  839.  
  840. ? q.empty;                     or q.empty();
  841.  false
  842.  
  843. ? q.dequeue;                   or q.dequeue();
  844.  5
  845.  
  846. ? q.empty;                     or q.empty();
  847.  true
  848.  
  849. ? q;
  850.  object              this shows the printed representation of an object
  851.  
  852. A second queue may be instantiated by using the new operation again.
  853.  
  854.  
  855.  
  856.  
  857.  
  858.  
  859.  
  860.  
  861.  
  862.                                      Page 14
  863.  
  864.  
  865.  
  866. p=new queue([]);
  867.  
  868. and an arbitrary number of queues may be created in this way.
  869.  
  870. The function definitions may optionally be preceded by the keyword
  871. public: to indicate that they are exported or made visible outside
  872. the class. If the keyword public: is not used, the default is public.
  873.  
  874. There are cases when one wants to define functions that are private.
  875. In this situation, the keywords private: and public: are used
  876. (in that order). An example of a priority queue follows.
  877.  
  878. class pqueue(rep) {
  879.  
  880. private: insrt(x,y) {if(y == []) {rep = [x]; return rep;} else
  881.                      if(x < hd y) {rep = [x] conc y;return rep;} else
  882.                      {rep = [hd y] conc insrt(x,tl y);
  883.                      return rep;}}
  884.  
  885. public: insert(x) {rep = insrt(x,rep); return rep;}
  886.         remove(;x) { if(rep == []) return "queue empty";
  887.                   x = hd rep; rep = tl rep; return x;} };
  888.  
  889.  
  890. The private declaration must be given first, followed by the public
  891. declaration. The last statement in the insert function returns the
  892. value of rep so that the user can see that the items are inserted in
  893. sorted order.Alternatively, the string "ok" could be returned.
  894. Note the declaration of the local variable x in the header of the
  895. remove function. The following sequence of operations show calls to
  896. the insert and remove functions:
  897.  
  898. ? q= new pqueue([]);
  899.  
  900. ? q.insert(3);
  901.  [3]
  902. ? q.insert(2);
  903.  [2,3]
  904. ? q.insert(9);
  905.  [2,3,9]
  906. ? q.insert(7);
  907.  [2,3,7,9]
  908. ? q.remove;
  909.  2
  910. ? q.remove;
  911.  3
  912. ? q.remove;
  913.  7
  914. ? q.remove;
  915.  9
  916. ? q.remove;
  917.  queue empty
  918.  
  919.  
  920.  
  921.  
  922.  
  923.  
  924.  
  925.  
  926.  
  927.  
  928.                                      Page 15
  929.  
  930.  
  931. System Commands
  932.  
  933. The help command produces the following menu:
  934.  
  935. 1 commands 2 fundef 3 statements 4 sets 5 maps 6 sequences 7 structs 8 quit
  936.  
  937. A "quick reference" screen showing functionality and syntax of Proxy
  938. constructs is obtained by selecting one of the above numbers. The results
  939. of selecting individual numbers is shown below.
  940.  
  941. 1
  942.  
  943. COMMANDS
  944. Type of Command                Example
  945.  
  946. (1) an expression              x + 3 ;
  947. (2) function definition        fun(y) {return y+1;};
  948. (3) assignment                 y = 17;
  949. (4) function call              fun(3);
  950. (5) struct declaration         struct empl {age,citizen;};
  951. (6) struct instantiation       p = new empl(25, true);
  952. (7) struct component update    p.age = 26;
  953. (8) map update                 table[3]= 4;
  954. (9) class definition           class stack(rep) {
  955.                                 push(x) {rep = [x] conc rep}
  956.                                 top() {return hd rep;}
  957.                                 pop() {rep= tl rep;} };
  958. (10) class instantiation       s= new stack([]);
  959. (11) load command              load "topsort.prx";
  960. (12) transcript command        transcript "session.txt";
  961. (13) help command              help;
  962. (14) exit command              exit;
  963. 1 commands 2 fundef 3 statements 4 sets 5 maps 6 sequences 7 records 8 quit
  964. 2
  965.  
  966. FUNCTION DEFINITION
  967.  
  968. iden ( op-param-list op-decl)  function definition
  969.   block ;                      where op-param-list is an
  970.                                optional parameter list,
  971.                                op-decl is an optional list
  972.                                of local variables with the
  973.                                form   ;iden-list and block
  974.                                consists of one or more
  975.                                statements enclosed by
  976.                                braces
  977.  
  978.                                Example
  979.  
  980.                                fact(n) { if (n=0) return 1;
  981.                                  else return n*fact(n-1);};
  982. 1 commands 2 fundef 3 statements 4 sets 5 maps 6 sequences 7 records 8 quit
  983. 3
  984.  
  985.  
  986.  
  987.  
  988.  
  989.  
  990.  
  991.  
  992.  
  993.  
  994.                                      Page 16
  995.  
  996.  
  997. STATEMENTS
  998.  
  999. left-hand-value = expr ;       simple assignment, map update,
  1000.                                or struct component update
  1001. if ( expr ) stat1              conditional statement - form1
  1002. if ( expr ) stat1 ;            conditional statement - form2
  1003.    else stat2
  1004. while ( expr ) stat            while statement
  1005. for iden <- expr ; stat        for statament
  1006. return ;                       return statement - form1
  1007. return expr;                   return statement - form2
  1008. iden ( expr-list );            function call
  1009. { stat1 ; ... statn ; }        block
  1010. open(iden,"r") ;               open read statement
  1011. open(iden,"w") ;               open write statement
  1012. close(iden) ;                  close statement
  1013. readln(v1,...,vn) ;            readln statement
  1014. readln(iden,v1,...vn) ;        readln file statement
  1015. writeln(v1,...,vn) ;           writeln statement
  1016. writeln(iden,v1,...,vn) ;      writeln file statement
  1017. 1 commands 2 fundef 3 statements 4 sets 5 maps 6 sequences 7 records 8 quit
  1018. 4
  1019.  
  1020. SETS
  1021. { e1, e2, ..., en}             set enumeration
  1022. { e1 .. ek}                    set of integers from e1 to ek
  1023. {}                             empty set
  1024. { e : x <- s }                 set comprehension
  1025. { e : x <- s ; b }             set comprehension with boolean
  1026. { e : x <- s1 , y <- s2 }         s1, s2 are sets
  1027. { e : x <- s1 , y <- s2 ; b }     b is a boolean
  1028. e in s                         set membership
  1029. e notin s                      set nonmembership
  1030. s1 inter s2                    set intersection
  1031. s1 U s2                        set union
  1032. s1 diff s2                     set difference
  1033. s1 subset s2                   subset
  1034. union s                        distributed union
  1035. card s                         cardinality of a set
  1036. s1 == s2                       set equality
  1037. the s                          element of singleton set
  1038. oneof s                        arbitrary member of set
  1039. (all x in s ; b )              universal quantifier
  1040. (exists x in s ; b )           existential quantifier
  1041. 1 commands 2 fundef 3 statements 4 sets 5 maps 6 sequences 7 records 8 quit
  1042. 5
  1043.  
  1044. MAPS
  1045.  
  1046. { d1 -> r1, ..., dn -> rn }    map enumeration
  1047. {}                             empty map
  1048. { x -> e1 : x <- e2 }          map construction
  1049. { x -> e1 : x <- e2 ; b }      map construction with boolean
  1050. dom m                          domain of map m
  1051.  
  1052.  
  1053.  
  1054.  
  1055.  
  1056.  
  1057.  
  1058.  
  1059.  
  1060.                                      Page 17
  1061.  
  1062.  
  1063. rng m                          range of map m
  1064. m dr s                         domain restriction (s is a set)
  1065. m ds s                         domain subtraction (s is a set)
  1066. inverse m                      inverse of m
  1067. m im s                         image of m (s is a set)
  1068. m[x]                           application
  1069. m[x,r]                         application with default error return
  1070. m1 overwr m2                   overwrite
  1071. m[d]= r                        map update
  1072. first p                        first element of ordered pair
  1073. second p                       second element of ordered pair
  1074. 1 commands 2 fundef 3 statements 4 sets 5 maps 6 sequences 7 records 8 quit
  1075. 6
  1076.  
  1077. SEQUENCES
  1078. [ e1, e2, ..., en]             sequence enumeration
  1079. [ e1 .. ek ]                   sequence of integers from e1 to ek
  1080. []                             empty sequence
  1081. [ e : x <- s ]                 sequence construction
  1082. [ e : x <- s ; b ]             sequence construction with boolean
  1083. [ e : x <- s1 , y <- s2 ]        s1, s2 are sequences
  1084. [ e : x <- s1 , y <- s2 ; b ]    b is a boolean
  1085. len s                          length of a sequence
  1086. s1 == s2                       sequence equality
  1087. s1 conc s2                     concatenation
  1088. s[i]                           selection
  1089. s[i,r]                         selection with default error return
  1090. hd s                           head of a sequence
  1091. tl s                           tail of a sequence
  1092. butlast s                      first n-1 elements
  1093. last s                         [s[len s]]
  1094. dom s                          set of indices of s
  1095. rng s                          set of elements of s
  1096. seq2map s                      convert sequence to a map
  1097. map2seq m                      convert map to a sequence
  1098. 1 commands 2 fundef 3 statements 4 sets 5 maps 6 sequences 7 records 8 quit
  1099. 7
  1100.  
  1101. STRUCTS
  1102.  
  1103. struct sname { f1,...,fn; };   struct declaration
  1104. new sname(e1, ..., en)         struct instantiation
  1105. s . fi ;                       struct component selection
  1106. s . fi = e ;                   struct component update
  1107. 1 commands 2 fundef 3 statements 4 sets 5 maps 6 sequences 7 records 8 quit
  1108.  
  1109. The load command (an example of which is given above) is used to load
  1110. Proxy commands from a file. The commands are inserted in a file as
  1111. if they were being typed at the command line, the only difference being
  1112. that the last line in the file must contain the single token: end.
  1113. Be careful not to insert more than one command on a line. For example,
  1114. x=2; y=3; is wrong because only the first assignment would be executed.
  1115. A function or class definition, however, consists of only a single
  1116. command, although it can take up more than one line.
  1117.  
  1118.  
  1119.  
  1120.  
  1121.  
  1122.  
  1123.  
  1124.  
  1125.  
  1126.                                      Page 18
  1127.  
  1128.  
  1129.  
  1130. The transcript command (an example of which is given above) is used to
  1131. record in a file all subsequent interactions of user inputs (keystrokes)
  1132. and resulting Proxy outputs.
  1133.  
  1134. The exit command terminates execution of the Proxy interpreter and
  1135. returns to the DOS prompt.
  1136.  
  1137. USING STATEMENTS
  1138.  
  1139. A statement is either a simple statement or a block (see below),
  1140. which is a sequence of statements delimited by curly brackets.
  1141.  
  1142. Assignment Statement
  1143.  
  1144. identifier = expression ;       expression is evaluated and the
  1145.                                 resulting value is stored in
  1146.                                 identifier. Examples are:
  1147.  
  1148. x = {2, 3, 5, 7} ;              simple assignment
  1149. m["Joe"] = 30;                  map update
  1150. p.r = {1->2, 3->4};             struct update
  1151.  
  1152. Conditional Statement
  1153.  
  1154. The conditional or if-statement may take one of the following
  1155. forms:
  1156.  
  1157. if ( expr ) stat1                  in both cases, expr is evaluated;
  1158.                                    if it evaluates to true then stat1
  1159. if ( expr ) stat1 ; else stat2     is executed. If it evaluates to
  1160.                                    false, in the first case nothing
  1161.                                    happens; in the second case stat2
  1162.                                    is executed. Examples are:
  1163.  
  1164. if (x < 2) y = 0;
  1165. if (n == 0 ) f = 1; else f = n * f;
  1166.  
  1167. While statement
  1168.  
  1169. while ( expr ) stat                expr is evaluated; as long as its
  1170.                                    value is true, stat is executed,
  1171.                                    and expr is reevaluated; when its
  1172.                                    value is false, the following
  1173.                                    statement is executed. Example:
  1174.  
  1175. while (n <= 10) n=n+1;
  1176.  
  1177. For statement
  1178.  
  1179. for identifier <- expr ; stat      expr is evaluated and identifier
  1180.                                    is assigned the values of the
  1181.                                    resulting set or sequence; stat
  1182.                                    is executed for each of these
  1183.  
  1184.  
  1185.  
  1186.  
  1187.  
  1188.  
  1189.  
  1190.  
  1191.  
  1192.                                      Page 19
  1193.  
  1194.  
  1195.                                    assignments. Example:
  1196.  
  1197.  
  1198. for i <- {1..10}; writeln(i);
  1199.  
  1200.  
  1201. Return statement
  1202.  
  1203. The return statement may take one of the following forms:
  1204.  
  1205. return ;                           the enclosing function is terminated.
  1206.  
  1207. return expr ;                      expr is evaluated and the enclosing
  1208.                                    function is terminated with the value
  1209.                                    of expr as its returned value. Example
  1210.  
  1211. return n+1;
  1212.  
  1213. I/O statements:
  1214.  
  1215. open(string,"r");                  Opens a file for reading given by
  1216.                                    string, and returns a file handle.
  1217.  
  1218. h = open("data.txt","r");
  1219.  
  1220. open(string,"w") ;                 Opens a file for writing given by
  1221.                                    string, and returns a file handle.
  1222.  
  1223. close(identifier) ;                Closes the file whose handle is
  1224.                                    given by identifier.
  1225.  
  1226. close(h);
  1227.  
  1228. writeln(v1,...,vn) ;               The scalar values or scalar valued
  1229.                                    variables vi (integer, real, string,
  1230.                                    boolean) are printed on one line
  1231.                                    separated by spaces.
  1232.  
  1233. writeln(123,r,"order");
  1234.  
  1235. writeln(identifier,v1,...,vn) ;    The values v1,...vn are output to
  1236.                                    the file whose handle is given by
  1237.                                    identifier.
  1238.  
  1239. writeln(h,123,r,"order");
  1240.  
  1241. readln(v1,...,vn) ;                The variables v1,...vn (which must be
  1242.                                    global) are assigned the corresponding
  1243.                                    values input at the keyboard.
  1244.  
  1245. readln(a,b,c);
  1246.  
  1247. readln(identifier,v1,...vn) ;      The variables v1,...vn are assigned
  1248.                                    the corresponding values in the file
  1249.  
  1250.  
  1251.  
  1252.  
  1253.  
  1254.  
  1255.  
  1256.  
  1257.  
  1258.                                      Page 20
  1259.  
  1260.  
  1261.                                    whose handle is given by identifier.
  1262.                                    If there are no more values in the file
  1263.                                    to read, the global variable eof has
  1264.                                    the value true, otherwise it has the
  1265.                                    value false.
  1266.  
  1267. fun() {readln(h,a,b,c);
  1268.        while(!eof) {writeln(a,b,c);
  1269.                     readln(h,a,b,c);}
  1270.       };
  1271.  
  1272. Function  call
  1273.  
  1274. identifier ( expr-list ) ;         Each expr in expr-list is evaluated
  1275.                                    and the function represented by
  1276.                                    identifier is called with the
  1277.                                    resulting arguments. If the function
  1278.                                    call is not contained in an expression
  1279.                                    i.e. it appears in a statement
  1280.                                    context, the resulting value is
  1281.                                    discarded.
  1282.  
  1283. Block
  1284.  
  1285. A sequence of statements may be grouped together to form a block
  1286. by enclosing them within curly brackets:
  1287.  
  1288. { stat1 ;
  1289.   stat2 ;
  1290.   ...
  1291.   statn ;
  1292. }                                  Notice that there is no semi-colon
  1293.                                    after the closing bracket. Example:
  1294.  
  1295. while (bal>0) {int=bal*r;am=pay-int;bal=bal-am;n=n+1;}
  1296.  
  1297.  
  1298. Comments
  1299.  
  1300. The delimiter // starts a comment that terminates at the end of the
  1301. line on which it occurs. It may be preceded by a statement (not an
  1302. expression), whitespace or may appear at the beginning of the line.
  1303.  
  1304. TYPE PREDICATES
  1305.  
  1306. The following predicates are supplied to test the type of a given value.
  1307.  
  1308. is_number                      is_map
  1309. is_boolean                     is_seq
  1310. is_string                      is_struct
  1311. is_set
  1312.  
  1313. Example:
  1314.  
  1315.  
  1316.  
  1317.  
  1318.  
  1319.  
  1320.  
  1321.  
  1322.  
  1323.  
  1324.                                      Page 21
  1325.  
  1326.  
  1327. is_number 3.14159;             returns true
  1328.  
  1329. CLASS CONSTRUCTORS
  1330.  
  1331. When a class constructor is defined by the user, by declaring a method
  1332. with the same name as the class, the corresponding class object will
  1333. be initialized automatically when it is instantiated. Taking the queue
  1334. example again:
  1335.  
  1336. class queue(;rep) {
  1337.  
  1338. queue() {rep=[];}
  1339. enqueue(x) {rep = rep conc [x];}
  1340. dequeue(;y) {y = hd rep; rep = tl rep; return y;{{;
  1341.  
  1342. An instantiation for this class would have the syntax
  1343.  
  1344. iden = new queue();
  1345.  
  1346. where iden represents the name of the instantiated object.
  1347.  
  1348. Note that rep is defined as a local variable of the class, and that
  1349. the first method, named queue, initializes rep to the empty sequence.
  1350. When an object is instantiated, i.e. q = new queue(), the rep of that
  1351. object will be initialized.
  1352.  
  1353. SCHEME INTERFACE
  1354.  
  1355. Proxy is implemented by translating expressions and function definitions
  1356. into Scheme which is then executed by a Scheme interpreter. This
  1357. implementation allows Proxy functions to call Scheme functions which
  1358. can then send back results to the Proxy program. Since the list is the
  1359. quintessential data structure in Scheme, and since sets, maps and
  1360. sequences in Proxy are implemented in terms of lists, we provide
  1361. transition functions to perform the conversions. In going from Proxy
  1362. to Scheme, we use
  1363.  
  1364.      $set2lst, $seq2lst, $map2lst     (set, seq, map to list)
  1365.  
  1366. and from Scheme to Proxy, we use
  1367.  
  1368.      $mkset, $mkseq, $mkmap           (list to set, seq, map)
  1369.  
  1370. The $ prefix tells the translator that the function is to be found
  1371. in the Scheme name space rather than in the Proxy name space. By the
  1372. same token, variables in the Scheme name space must also be prefixed
  1373. by a $.
  1374.  
  1375. Consider the following artificial example. We first define a Scheme
  1376. function called fun, which when applied to a list of lists, returns
  1377. a list of all the second elements. In other words,
  1378.  
  1379. (fun '((1 2) (3 4)))             returns (2 4)
  1380.  
  1381.  
  1382.  
  1383.  
  1384.  
  1385.  
  1386.  
  1387.  
  1388.  
  1389.  
  1390.                                      Page 22
  1391.  
  1392.  
  1393. Fun is defined at the Proxy prompt, i.e.
  1394.  
  1395. Continue? : (run) / (exit)
  1396.  
  1397. > (define (fun x) (map (lambda (x) (cadr x)) x))
  1398.  
  1399. (run)
  1400.  
  1401. ? $mkseq ( $fun ( $map2lst ( {1 -> 2, 3 -> 4} )));   returns [2, 4]
  1402.  
  1403. First, $map2lst is applied to the map to produce the list of lists:
  1404. ((1 2) (3 4)). Then the Scheme function fun is applied to this to
  1405. produce the list (2 4). Finally $mkseq is applied to this to produce
  1406. the Proxy sequence [2, 4].
  1407.  
  1408.  
  1409. AN EXAMPLE
  1410.  
  1411. A "financial history" supports the following transactions:
  1412.  
  1413. receive(amount,source) records that amount (an integer) was
  1414.                        received from source (a string)
  1415. spend(amount,reason)   records that amount (an integer) was
  1416.                        spent for reason (a string)
  1417. totalrec(source)       returns the total amount received from
  1418.                        source
  1419. totalspent(reason)     returns the total amount spent for
  1420.                        reason
  1421. cashonhand             records the cash on hand (an integer)
  1422.  
  1423. There are three global variables representing the state: cashonhand,
  1424. inc (a map from source to amount), and exp (a map from reason to
  1425. amount).
  1426.  
  1427. The Proxy program for this example is contained in the file FINANCE.PRX
  1428. and is shown here exactly as contained in the file. Since types are not
  1429. declared in Proxy, it is good practice to specify the types of the state
  1430. components are shown below.
  1431.  
  1432. // state components:
  1433.  
  1434. // cashonhand: integer
  1435. // inc: map(string,integer)
  1436. // exp: map(string,integer)
  1437.  
  1438. receive(amount,source) {cashonhand=cashonhand+amount;
  1439.                   inc[source]=inc[source,0]+amount;
  1440.                   return "ok";};
  1441. spend(amount,reason) {if(amount>cashonhand) return "Insufficient funds";
  1442.                  cashonhand=cashonhand-amount;
  1443.                  exp[reason]=exp[reason,0]+amount;
  1444.                  return "ok";};
  1445. totalrec(source) {return inc[source,0];};
  1446. totalspent(reason) {return exp[reason,0];};
  1447.  
  1448.  
  1449.  
  1450.  
  1451.  
  1452.  
  1453.  
  1454.  
  1455.  
  1456.                                      Page 23
  1457.  
  1458.  
  1459. cashonhand=100;
  1460. end
  1461.  
  1462. The cashonhand is initialized to 100 and is incremented in the receive
  1463. function and decremented in the spend function. If the amount to be
  1464. spent is greater than the cashonhand, the spend function returns
  1465. "Insufficient funds". The map 'inc' consists of a set of ordered pairs
  1466. where the first element of a pair is the source of a receipt, and the
  1467. second element is the total amount received from this source. The map
  1468. 'exp' contains the pairs where the first element is the reason for the
  1469. expense and the second element is the total amount spent. The default
  1470. error return, for example inc[source,0], handles the case where a
  1471. source appears for the first time and therefore does not occur as a
  1472. domain element in the map. The totalrec and totalspent functions use map
  1473. application to return the total amounts received and spent respectively.
  1474. Here again, the default error return will return 0 if the source or
  1475. reason does not appear in the map.
  1476.  
  1477. Another way of writing the program is to leave out the return "ok"
  1478. statements in the spend and receive functions. The effect of these
  1479. changes is that no output will be obtained when they are invoked,
  1480. except in the case of insufficient funds.
  1481.  
  1482. A possible sequence of operations follows.
  1483.  
  1484. ? cashonhand;
  1485.  100
  1486. ? spend(50,"food");
  1487.  "ok"
  1488. ? receive(100,"bank");
  1489.  "ok"
  1490. ? cashonhand;
  1491.  150
  1492.  
  1493. ? spend(100,"food");
  1494.  "ok"
  1495. ? totalspent("food");
  1496.  150
  1497.  
  1498. ? spend(150,"rent");
  1499.  "Insufficient funds"
  1500.  
  1501. ANOTHER EXAMPLE
  1502.  
  1503. An Electronic Mail System (Email) is to be designed to provide
  1504. communication between users of the system. The following operations
  1505. must be supported:
  1506.  
  1507. Signon(u,p) - By giving a valid user name and user-selected password,
  1508.               a user should be permitted access to the system.
  1509.  
  1510. Signoff(u)  - The user may remove himself from the system
  1511.  
  1512. Add(u,n,p)  - The "super" user may supply a name and password in order
  1513.  
  1514.  
  1515.  
  1516.  
  1517.  
  1518.  
  1519.  
  1520.  
  1521.  
  1522.                                      Page 24
  1523.  
  1524.  
  1525.               to add a new user to the list of authorized users.
  1526.  
  1527. Drop(u,n)   - The "super" user may delete a user name from the list
  1528.               of authorized users.
  1529.  
  1530. Send(u,t,n) - By giving the text of a message and name of a receiver,
  1531.               a user can place a message into a receiver's queue.
  1532.  
  1533. Read(u)    - A user can issue a Read command to examine his/her queue.
  1534.              The response should be the sender's name and text of the
  1535.              first message (if any). Successive reads will return
  1536.              additional messages (if any).
  1537.  
  1538. Delete(u)  - After reading a message, the user may issue a Delete
  1539.              command to delete the message just read.
  1540.  
  1541. Reset(u)   - This causes the next Read command to begin at the head
  1542.              of the queue.
  1543.  
  1544. Notice that the first parameter of each operation represents the
  1545. name of the user invoking the operation.
  1546.  
  1547. A Proxy program for this application is contained in the file EMAIL.PRX.
  1548. This solution illustrates the use of return messages to signal exceptions.
  1549. A queue class is first defined with the following operations: read,
  1550. write, reset and delete. This class has two instance variables: procd
  1551. and remdr, both sequences. procd represents the queue of mail messages
  1552. already processed, and remdr represents the queue of messages not
  1553. yet read. The queue class acts like a sequential file and can be
  1554. used in any application requiring a data structure with these character-
  1555. istics. The state components are:
  1556.  
  1557.      up (map from user to password)
  1558.      uq (map from user to mail-queue)
  1559.      so (set of users who are signed on)
  1560.  
  1561. // state components
  1562.  
  1563. // up: map(string,string)
  1564. // uq: map(string,queue)
  1565. // so: set(string)
  1566.  
  1567. class queue(procd,remdr) {
  1568.  read() {var x;
  1569.           if(len remdr=0) return "empty queue";
  1570.           x:=hd remdr;
  1571.           remdr:=tl remdr;
  1572.           procd:=procd conc [x];
  1573.           return x;}
  1574.  write(msg) {remdr:=remdr conc [msg];}
  1575.  reset() {remdr:=procd conc remdr;
  1576.           procd:=[];}
  1577.  delete() {if(len procd=0) return "empty queue";
  1578.            procd:=butlast procd;} };
  1579.  
  1580.  
  1581.  
  1582.  
  1583.  
  1584.  
  1585.  
  1586.  
  1587.  
  1588.                                      Page 25
  1589.  
  1590.  
  1591.  
  1592. up:={"super" -> "super"};         // initialize super user with pw "super"
  1593. uq:={"super" -> new queue([],[])};// initialize mail-queue so super user
  1594.                                   // can send mail to him
  1595. mail :: sender text;              // mail is a struct with two fields:
  1596.                                   // sender and text
  1597. add(u,n,pw) {if (u /= "super") return {"not authorized",u};
  1598.              uq[n]:=new queue([],[]); // initializes mail-queue
  1599.              up[n]:=pw;               // initializes password
  1600.              return "ok";};
  1601. drop(u,n) {if (u /= "super") return {"not authorized",u};
  1602.            if (n notin dom up) return {"unknown user",n};
  1603.            up:=up ds {n};                // remove user and password
  1604.            uq:=uq ds {n};                // remove user and mail-queue
  1605.            if(n in so) so:=so diff {n};  // if user signed on, sign
  1606.            return "ok";};                // him off
  1607. signon(u,pw) {if (up[u,""] /= pw) return {"incorrect password",pw};
  1608.               so:=so U {u};              // sign him on
  1609.               return "ok";};
  1610. signoff(u) {if (u notin so) return {"not signed on",u};
  1611.             so:=so diff {u};             // sign him off
  1612.             return "ok";};
  1613. send(u,t,r) {var x; if (u notin so) return {"not signed on",u};
  1614.              if (r notin dom up) return {"unknown user",r};
  1615.              x:=uq[r];
  1616.              x.write(mk_mail(u,t));      // create mail and send
  1617.              return "ok";};
  1618. read(u) {var x;if (u notin so) return {"not signed on",u};
  1619.          x:=uq[u];
  1620.          return x.read;};                // read mail
  1621. reset(u) {var x;if (u notin so) return {"not signed on",u};
  1622.           x:=uq[u];
  1623.           x.reset;                       // reset mail-queue
  1624.           return "ok";};
  1625. delete(u) {var x;if (u notin so) return {"not signed on",u};
  1626.            x:=uq[u];
  1627.            x.delete;                     // delete mail
  1628.            return "ok";};
  1629. so:= {};
  1630. end
  1631.  
  1632. The following sequence of messages and responses shows the application
  1633. of the Email operations.
  1634.  
  1635. ? add("super","joe",123);
  1636.  "ok"
  1637. ? add("super","mike",456);
  1638.  "ok"
  1639. ? signon("joe",123);
  1640.  "ok"
  1641. ? signon("mike",455);
  1642.  "incorrect password"
  1643. ? signon("mike",456;
  1644.  "ok"
  1645.  
  1646.  
  1647.  
  1648.  
  1649.  
  1650.  
  1651.  
  1652.  
  1653.  
  1654.                                      Page 26
  1655.  
  1656.  
  1657. ? send("joe","hello","mike");
  1658.  "ok"
  1659. ? send("joe","there","mike");
  1660.  "ok"
  1661. ? send("joe","meet me","tom");
  1662.  {"unknown user","tom"}
  1663. ? read("mike");
  1664.  < "joe", "hello" >
  1665. ? read("mike");
  1666.  < "joe", "there" >
  1667. ? read("mike");
  1668.  "empty queue"
  1669. ? reset("mike");
  1670.  "ok"
  1671. ? read("mike");
  1672.  < "joe", "hello">
  1673. ? delete("mike");
  1674.  "ok"
  1675. ? read("mike");
  1676.  < "joe", "there" >
  1677. ? reset("mike");
  1678.  "ok"
  1679. ? read("mike");
  1680.  < "joe", "there" >
  1681. ? drop("joe","mike");
  1682.  {"not authorized","joe"}
  1683. ? signoff("joe");
  1684.  "ok"
  1685.  
  1686. This example illustrates the "me too" paradigm [1] for producing
  1687. prototypes in three steps:
  1688.  
  1689. (1) model step - identify the entities and associated operations of
  1690.                  an application. In this case, we selected mail and
  1691.                  queue as entities, and read, write, reset and
  1692.                  delete as operations on the queue.
  1693.  
  1694. (2) specification step - implement the entities and operations in
  1695.                          terms of sets, maps, sequences, etc.
  1696.                          We represented queue by a class with instance
  1697.                          variables procd and remdr. Mail was represented
  1698.                          by a struct with fields sender and text.
  1699.  
  1700. (3) validation step - the operations are executed to determine if the
  1701.                       model and implementation are appropriate.
  1702.  
  1703. The above steps are iterated as necessary until a satisfactory version
  1704. is obtained.
  1705.  
  1706. PROXY KEY WORDS
  1707.  
  1708. all                len
  1709. butlast            map2seq
  1710. card               new
  1711.  
  1712.  
  1713.  
  1714.  
  1715.  
  1716.  
  1717.  
  1718.  
  1719.  
  1720.                                      Page 27
  1721.  
  1722.  
  1723. class              notin
  1724. close              oneof
  1725. conc               open
  1726. dom                overwr
  1727. dr                 private
  1728. ds                 public
  1729. else               readln
  1730. eof                return
  1731. equiv              rng
  1732. exists             second
  1733. false              seq2map
  1734. first              struct
  1735. for                subset
  1736. hd                 the
  1737. if                 tl
  1738. im                 true
  1739. implies            U
  1740. in                 union
  1741. inter              while
  1742. inverse            writeln
  1743. last
  1744.  
  1745. REFERENCES
  1746.  
  1747. [1] Alexander, H. and Jones, V., Software Design and Prototyping using
  1748.     me too, Prentice-Hall, New York, 1990.
  1749.  
  1750. [2] Brooks, F.,The Mythical Man-Month. Addison-Wesley, Reading, MA, 1975.
  1751.  
  1752. [3] Jones, C.B., Systematic Software Development Using VDM, Prentice-Hall,
  1753.      New York, 1986.
  1754.  
  1755. [4] Hekmatpour, S. and Ince, D., Software Prototyping, Formal Methods and
  1756.      VDM, Addison-Wesley, Reading, MA, 1988.
  1757.  
  1758. [5] Schwartz, J.T. et al, Programming with Sets: An Introduction to SETL,
  1759.      Springer-Verlag, New York, 1986.
  1760.  
  1761. INDEX
  1762.  
  1763. assignment statement                3,8,10,12,15,17,18
  1764. block                               11,15,16,18,20
  1765. boolean type                        4,16,17,19
  1766. butlast operator                    9,10,11,17
  1767. cardinality operator                5,7,16
  1768. class definition                    12,13,15,17
  1769. classes                             2,12
  1770. close statement                     16
  1771. commands                            3,4,14,15,16,17
  1772. comments                            20
  1773. concatenation operator              8,17
  1774. conditional statement               16,18
  1775. default error return                7,9,17,21
  1776. difference operator                 5,16
  1777.  
  1778.  
  1779.  
  1780.  
  1781.  
  1782.  
  1783.  
  1784.  
  1785.  
  1786.                                      Page 28
  1787.  
  1788.  
  1789. distributed union operator          5,16
  1790. domain operator                     7,8,9,16,21
  1791. domain restriction operator         7,16
  1792. domain subtraction operator         7,16
  1793. existential quantifier              6,12,16
  1794. exit command                        3,15,18
  1795. first operator                      6,7,9,10,11,17
  1796. for statement                       18
  1797. function call                       15,16
  1798. function definition                 3,11,12,14,15
  1799. generator                           6,9
  1800. hd operator                         9,10,11,12,13,14,15,17
  1801. help command                        3,14,15
  1802. identifiers                         4,11,18,19,20
  1803. image operator                      7,17
  1804. instantiation, class                12,13,15
  1805. instantiation, struct               10,15,17
  1806. intersection operator               5,16
  1807. inverse operator                    7,11,17
  1808. i/o statement                       9
  1809. integer type                        4,9,11,12,16,17,19,20
  1810. last operator                       9,10,11,17
  1811. len operator                        7,8,9,10,11,12,13,17
  1812. load command                        3,15,17
  1813. local variables                     11,12,14,15
  1814. logical conjunction                 4
  1815. logical disjunction                 4
  1816. logical negation                    4
  1817. main                                11
  1818. map application                     7,17,21
  1819. map construction                    6,16
  1820. map enumeration                     16
  1821. map update                          8,15,17,18
  1822. map2seq operator                    9,11,17
  1823. maps                                4,6,7,15,16,17,25
  1824. membership operator                 5,16
  1825. modulo operator                     4
  1826. oneof operator                      5,11,16
  1827. open statement                      16,19
  1828. operators                           4,9,10,11
  1829. operator precedence                 11
  1830. overwrite operator                  8,17
  1831. primitive types                     4
  1832. private                             14
  1833. procedures                          11,12
  1834. public                              14
  1835. range operator                      7,8,9,16
  1836. readln statement                    16,19,20
  1837. real type                           4,19
  1838. return statement                    11,12,13,14,15,16,19
  1839. second operator                     6,7,9,17
  1840. seq2map operator                    9,11,17
  1841. sequence construction               17
  1842. sequence enumeration                17
  1843.  
  1844.  
  1845.  
  1846.  
  1847.  
  1848.  
  1849.  
  1850.  
  1851.  
  1852.                                      Page 29
  1853.  
  1854.  
  1855. sequence selection                  9,17
  1856. sequence range                      8
  1857. sequences                           4,8,9,10,15,16,17,25
  1858. set constructor                     5,6
  1859. set enumeration                     16
  1860. set range                           5
  1861. sets                                4,6,15,16,17,25
  1862. statements                          15,16,17,18,19,20
  1863. strings                             4,10
  1864. structs                             4,10,15,17
  1865. system commands                     3,14
  1866. the operator                        5
  1867. tl operator                         9,10,11,12,13,14,15,17
  1868. transcript command                  3,15,17
  1869. unary operators                     4,11
  1870. union operator                      5,11,16
  1871. universal quantifier                6,16
  1872. void                                11
  1873. while statement                     16,18,20
  1874. writeln statement                   16,19,20
  1875.  
  1876.  
  1877.  
  1878.  
  1879.  
  1880.  
  1881.  
  1882.  
  1883.  
  1884.  
  1885.  
  1886.  
  1887.  
  1888.  
  1889.  
  1890.  
  1891.  
  1892.  
  1893.  
  1894.  
  1895.  
  1896.  
  1897.  
  1898.  
  1899.  
  1900.  
  1901.  
  1902.  
  1903.  
  1904.  
  1905.  
  1906.  
  1907.  
  1908.  
  1909.  
  1910.  
  1911.  
  1912.  
  1913.  
  1914.  
  1915.  
  1916.  
  1917.  
  1918.                                      Page 30
  1919.  
  1920.  
  1921.